/*
 * servo.c
 *
 *  Created on: Feb 5, 2013
 *      Author: ostan

Program controls a servo motor. When button is pressed, the servo rotates in position 1, otherwise, it is in position 2.
LED is used for debugging.

Servo motor we want to control:
http://www.made-in-china.com/showroom/xiangyumodel/product-detailiMBxSeZDZAhJ/China-RC-Servo-Motor-DS44-.html

Important characteristics:
5)Pulse Width Scope: 900-2100μ s
6)Neutral pulse: 1500μ s


Pulses we want to feed to servo:
http://en.wikipedia.org/wiki/File:Sinais_controle_servomotor.JPG

The pinout of the servo:
http://www.fatlion.com/sailplanes/servos.html

 */

#include <avr/io.h>
#include <util/delay.h>


/**
 * set the state of servo control line
 * if state != 0, set high, otherwise, set output low.
 */
inline void setServoOutput(char state) {
	if (state) {
		PORTE |= 1<<PE4; // set the control output high
	} else {
		PORTE &= ~(1<<PE4); // set the control output low
	}
}

/**
 * Returns true (value other than zero) if button is pressed
 */
inline char buttonIsPressed(void) {
	return (PING & 1<<PG4);
}

/**
 * busy wait rutine
 */
void delay_us(int delay) {
	int i;
	for (i=0; i<delay; i++) {
		_delay_us(1);
	}
}

int main (void) {
	DDRE |= 1<<PE4; // set the PE4 pin as output (servo control output)

	// configure the button
	DDRG |= 1<<PG4; // set as input (Data Direction Register)
	PORTG |= 1<<PG4; // set the pull up resistor

	int pulse_us;
	while(1) {

		if(buttonIsPressed()) {
			pulse_us = 1800;
		} else {
			pulse_us = 1200;
		}

		setServoOutput(1);
		delay_us(pulse_us);
		setServoOutput(0);
		delay_us(20000-pulse_us);
	}

	return 0;
}
